//+------------------------------------------------------------------+
//|                       Canvas.mqh 动态绘图画布类头文件            |
//|                版权所有 2000-2025, MetaQuotes Ltd.              |
//|                        官方网址: https://www.mql5.com            |
//+------------------------------------------------------------------+
#include <Files/FileBin.h>  // 引入二进制文件操作类，用于位图文件读写
#include <Controls/Rect.h>  // 引入矩形/点操作类（CPoint），用于图形坐标计算

//+------------------------------------------------------------------+
//| 辅助宏定义                                                       |
//+------------------------------------------------------------------+
/**
 * @brief 符号判断宏：返回整数的符号（正数/零返回 1，负数返回 -1）
 * @param i [in] 待判断的整数
 * @return int - 符号值（1 或 -1）
 */
#define SIGN(i) ((i<0) ? -1 : 1)

//+------------------------------------------------------------------+
//| 颜色生成与解析宏（支持 XRGB/ARGB 格式，适配 MT5 颜色处理规则）    |
//+------------------------------------------------------------------+
/**
 * @brief 生成 XRGB 格式颜色（无透明度，Alpha 固定为 0xFF）
 * @param r [in] 红色通道（0-255）
 * @param g [in] 绿色通道（0-255）
 * @param b [in] 蓝色通道（0-255）
 * @return uint - XRGB 格式颜色值（二进制：0xFF RR GG BB）
 */
#define XRGB(r,g,b)    (0xFF000000|(uchar(r)<<16)|(uchar(g)<<8)|uchar(b))

/**
 * @brief 生成 ARGB 格式颜色（含透明度）
 * @param a [in] 透明度通道（0-255，0 全透明，255 不透明）
 * @param r [in] 红色通道（0-255）
 * @param g [in] 绿色通道（0-255）
 * @param b [in] 蓝色通道（0-255）
 * @return uint - ARGB 格式颜色值（二进制：AA RR GG BB）
 */
#define ARGB(a,r,g,b)  ((uchar(a)<<24)|(uchar(r)<<16)|(uchar(g)<<8)|uchar(b))

/**
 * @brief 为已有 RGB 颜色添加透明度
 * @param a [in] 透明度通道（0-255）
 * @param rgb [in] 已有 RGB 颜色值（低 24 位为 RR GG BB）
 * @return uint - ARGB 格式颜色值（Alpha 叠加后的结果）
 */
#define TRGB(a,rgb)    ((uchar(a)<<24)|(rgb))

/**
 * @brief 从颜色值中提取 RGB 部分（剔除 Alpha 通道）
 * @param clr [in] 完整颜色值（ARGB 或 XRGB 格式）
 * @return uint - 纯 RGB 颜色值（低 24 位有效）
 */
#define GETRGB(clr)    ((clr)&0xFFFFFF)

/**
 * @brief 从颜色值中提取 Alpha 通道
 * @param clr [in] 完整颜色值（ARGB 格式）
 * @return uchar - Alpha 通道值（0-255）
 */
#define GETRGBA(clr)   uchar((clr)>>24)

/**
 * @brief 从颜色值中提取红色通道
 * @param clr [in] 完整颜色值（ARGB 或 XRGB 格式）
 * @return uchar - 红色通道值（0-255）
 */
#define GETRGBR(clr)   uchar((clr)>>16)

/**
 * @brief 从颜色值中提取绿色通道
 * @param clr [in] 完整颜色值（ARGB 或 XRGB 格式）
 * @return uchar - 绿色通道值（0-255）
 */
#define GETRGBG(clr)   uchar((clr)>>8)

/**
 * @brief 从颜色值中提取蓝色通道
 * @param clr [in] 完整颜色值（ARGB 或 XRGB 格式）
 * @return uchar - 蓝色通道值（0-255）
 */
#define GETRGBB(clr)   uchar(clr)

/**
 * @brief 将 MT5 标准 COLOR_* 常量转换为 XRGB 格式
 * @param clr [in] MT5 颜色常量（如 COLOR_RED）
 * @return uint - XRGB 格式颜色值（Alpha 固定为 0xFF）
 */
#define COLOR2RGB(clr) (0xFF000000|(uchar(clr)<<16)|(uchar((clr)>>8)<<8)|uchar((clr)>>16))

/**
 * @brief 将 RGB 格式颜色转换为 MT5 标准 COLOR_* 格式
 * @param rgb [in] RGB 颜色值（低 24 位为 RR GG BB）
 * @return uint - MT5 标准颜色值
 */
#define RGB2COLOR(rgb) ((uchar(rgb)<<16)|(uchar((rgb)>>8)<<8)|uchar((rgb)>>16))

//+------------------------------------------------------------------+
//| 线条端点样式枚举（控制线条末端的绘制形态）                        |
//+------------------------------------------------------------------+
enum ENUM_LINE_END
  {
   LINE_END_ROUND,   // 圆形端点（线条末端为半圆，平滑过渡）
   LINE_END_BUTT,    // 平角端点（线条末端为直角，与线条方向垂直）
   LINE_END_SQUARE   // 方形端点（线条末端延伸出方形，长度为线条宽度的一半）
  };

//+------------------------------------------------------------------+
//| CCanvas 类                                                       |
//| 功能：MT5 动态绘图画布核心类，支持位图资源管理、2D 图形绘制、文本渲染 |
//| 核心特性：                                                      |
//|  1. 支持多种画布创建模式（独立资源、绑定图表位图/标签、从文件加载）  |
//|  2. 提供完整的 2D 图形绘制接口（直线、多边形、椭圆等，含抗锯齿）    |
//|  3. 支持文本渲染（字体、大小、角度自定义）及位图文件读写           |
//|  4. 适配 MT5 图表对象模型，可直接在图表上显示并更新                |
//+------------------------------------------------------------------+
class CCanvas
  {
private:
   uint              m_style;                  // 线条样式模板（二进制位掩码，控制虚实线等）
   uint              m_style_idx;              // 线条样式模板当前位索引（用于循环应用样式）
   static uint       m_default_colors[9];      // 默认颜色数组（预定义 9 种常用颜色，见下方初始化）

protected:
   long              m_chart_id;               // 绑定的图表 ID（0 表示未绑定图表）
   string            m_objname;                // 关联的图表对象名称（如 OBJ_BITMAP 类型对象）
   ENUM_OBJECT       m_objtype;                // 关联的图表对象类型（OBJ_BITMAP/OBJ_BITMAP_LABEL 等）
   string            m_rcname;                 // 动态资源名称（MT5 内部资源标识，格式为 "::资源名"）
   int               m_width;                  // 画布宽度（像素）
   int               m_height;                 // 画布高度（像素）
   ENUM_COLOR_FORMAT m_format;                 // 颜色处理格式（如 COLOR_FORMAT_XRGB_NOALPHA，见 MT5 枚举定义）
   //--- 文本渲染相关成员
   string            m_fontname;               // 字体名称（如 "Arial"）
   int               m_fontsize;               // 字体大小（负值表示像素单位，如 -12 表示 12px）
   uint              m_fontflags;              // 字体样式标志（如 FS_BOLD/FS_ITALIC，见 MT5 常量）
   uint              m_fontangle;              // 文本倾斜角度（相对于 X 轴，单位：0.1 度，0 表示水平）
   //--- 像素数据存储
   uint              m_pixels[];               // 像素数组（存储画布所有像素的颜色值，顺序：行优先）

public:
   /**
    * @brief 构造函数：初始化 CCanvas 画布实例
    * @details 初始化所有成员变量为默认值（画布尺寸为 0，未绑定图表，字体默认为 Arial -12px）
    */
                     CCanvas(void);

   /**
    * @brief 析构函数：销毁 CCanvas 画布实例
    * @details 自动调用 Destroy 方法释放资源（像素数组、关联图表对象、动态资源）
    */
                    ~CCanvas(void);

   //--- 画布创建/绑定/销毁接口
   /**
    * @brief 创建独立的动态画布资源（不绑定图表对象）
    * @param name [in] 资源名称前缀（最终会添加唯一标识，避免冲突）
    * @param width [in] 画布宽度（像素，必须 >0）
    * @param height [in] 画布高度（像素，必须 >0）
    * @param clrfmt [in] 颜色处理格式（默认：COLOR_FORMAT_XRGB_NOALPHA，无透明度）
    * @return bool - 操作结果：true 表示创建成功，false 表示尺寸无效或资源创建失败
    */
   virtual bool      Create(const string name,const int width,const int height,ENUM_COLOR_FORMAT clrfmt=COLOR_FORMAT_XRGB_NOALPHA);

   /**
    * @brief 创建绑定到图表的位图对象（OBJ_BITMAP 类型，基于时间价格坐标）
    * @param name [in] 图表对象名称（需唯一，如 "Canvas_Bitmap"）
    * @param time [in] 位图左上角对应的时间坐标（图表时间轴）
    * @param price [in] 位图左上角对应的价格坐标（图表价格轴）
    * @param width [in] 画布宽度（像素，必须 >0）
    * @param height [in] 画布高度（像素，必须 >0）
    * @param clrfmt [in] 颜色处理格式（默认：COLOR_FORMAT_XRGB_NOALPHA）
    * @return bool - 操作结果：true 表示创建成功，false 表示参数无效或对象创建失败
    */
   bool              CreateBitmap(const string name,const datetime time,const double price,
                                  const int width,const int height,ENUM_COLOR_FORMAT clrfmt=COLOR_FORMAT_XRGB_NOALPHA);

   /**
    * @brief 创建绑定到指定图表子窗口的位图对象（OBJ_BITMAP 类型）
    * @param chart_id [in] 目标图表 ID（0 表示当前图表）
    * @param subwin [in] 图表子窗口索引（0 表示主窗口，1 及以上表示指标子窗口）
    * @param name [in] 图表对象名称（需唯一）
    * @param time [in] 位图左上角对应的时间坐标
    * @param price [in] 位图左上角对应的价格坐标
    * @param width [in] 画布宽度（像素，必须 >0）
    * @param height [in] 画布高度（像素，必须 >0）
    * @param clrfmt [in] 颜色处理格式（默认：COLOR_FORMAT_XRGB_NOALPHA）
    * @return bool - 操作结果：true 表示创建成功，false 表示参数无效或对象创建失败
    */
   bool              CreateBitmap(const long chart_id,const int subwin,const string name,
                                  const datetime time,const double price,const int width,const int height,
                                  ENUM_COLOR_FORMAT clrfmt=COLOR_FORMAT_XRGB_NOALPHA);

   /**
    * @brief 创建绑定到图表的位图标签（OBJ_BITMAP_LABEL 类型，基于屏幕像素坐标）
    * @param name [in] 图表对象名称（需唯一）
    * @param x [in] 标签左上角 X 坐标（相对于图表窗口，像素）
    * @param y [in] 标签左上角 Y 坐标（相对于图表窗口，像素）
    * @param width [in] 画布宽度（像素，必须 >0）
    * @param height [in] 画布高度（像素，必须 >0）
    * @param clrfmt [in] 颜色处理格式（默认：COLOR_FORMAT_XRGB_NOALPHA）
    * @return bool - 操作结果：true 表示创建成功，false 表示参数无效或对象创建失败
    */
   bool              CreateBitmapLabel(const string name,const int x,const int y,
                                       const int width,const int height,ENUM_COLOR_FORMAT clrfmt=COLOR_FORMAT_XRGB_NOALPHA);

   /**
    * @brief 创建绑定到指定图表子窗口的位图标签（OBJ_BITMAP_LABEL 类型）
    * @param chart_id [in] 目标图表 ID（0 表示当前图表）
    * @param subwin [in] 图表子窗口索引（0 表示主窗口）
    * @param name [in] 图表对象名称（需唯一）
    * @param x [in] 标签左上角 X 坐标（相对于子窗口，像素）
    * @param y [in] 标签左上角 Y 坐标（相对于子窗口，像素）
    * @param width [in] 画布宽度（像素，必须 >0）
    * @param height [in] 画布高度（像素，必须 >0）
    * @param clrfmt [in] 颜色处理格式（默认：COLOR_FORMAT_XRGB_NOALPHA）
    * @return bool - 操作结果：true 表示创建成功，false 表示参数无效或对象创建失败
    */
   bool              CreateBitmapLabel(const long chart_id,const int subwin,const string name,
                                       const int x,const int y,const int width,const int height,
                                       ENUM_COLOR_FORMAT clrfmt=COLOR_FORMAT_XRGB_NOALPHA);

   /**
    * @brief 绑定到已存在的图表位图标签（OBJ_BITMAP_LABEL 类型）
    * @param chart_id [in] 目标图表 ID（0 表示当前图表）
    * @param objname [in] 已存在的图表对象名称（必须是 OBJ_BITMAP_LABEL 类型）
    * @param clrfmt [in] 颜色处理格式（默认：COLOR_FORMAT_XRGB_NOALPHA）
    * @return bool - 操作结果：true 表示绑定成功，false 表示对象不存在或类型不匹配
    */
   virtual bool      Attach(const long chart_id,const string objname,ENUM_COLOR_FORMAT clrfmt=COLOR_FORMAT_XRGB_NOALPHA);

   /**
    * @brief 绑定到已存在的图表位图标签并重置画布尺寸
    * @param chart_id [in] 目标图表 ID（0 表示当前图表）
    * @param objname [in] 已存在的图表对象名称（必须是 OBJ_BITMAP_LABEL 类型）
    * @param width [in] 新的画布宽度（像素，必须 >0）
    * @param height [in] 新的画布高度（像素，必须 >0）
    * @param clrfmt [in] 颜色处理格式（默认：COLOR_FORMAT_XRGB_NOALPHA）
    * @return bool - 操作结果：true 表示绑定并重置成功，false 表示参数无效或对象操作失败
    */
   virtual bool      Attach(const long chart_id,const string objname,const int width,const int height,ENUM_COLOR_FORMAT clrfmt=COLOR_FORMAT_XRGB_NOALPHA);

   /**
    * @brief 销毁画布资源（释放像素数组、删除关联图表对象、释放动态资源）
    * @details 调用后画布回到未初始化状态，需重新 Create/Attach 才能使用
    */
   virtual void      Destroy(void);

   //--- 画布属性访问接口（只读）
   /**
    * @brief 获取关联的图表对象名称
    * @return string - 图表对象名称（如 "Canvas_Bitmap_Label"），未绑定对象返回空字符串
    */
   string            ChartObjectName(void)          const { return(m_objname); }

   /**
    * @brief 获取动态资源名称
    * @return string - 资源名称（格式为 "::资源名"），未创建资源返回空字符串
    */
   string            ResourceName(void)             const { return(m_rcname);  }

   /**
    * @brief 获取画布宽度
    * @return int - 宽度（像素），未初始化返回 0
    */
   int               Width(void)                    const { return(m_width);   }

   /**
    * @brief 获取画布高度
    * @return int - 高度（像素），未初始化返回 0
    */
   int               Height(void)                   const { return(m_height);  }

   //--- 画布更新与调整接口
   /**
    * @brief 更新画布显示（将像素数组数据同步到动态资源，并可选刷新图表）
    * @param redraw [in] 是否刷新图表（true 表示立即刷新，false 表示仅同步资源不刷新）
    */
   void              Update(const bool redraw=true);

   /**
    * @brief 调整画布尺寸（会清空原有像素数据）
    * @param width [in] 新宽度（像素，必须 >0）
    * @param height [in] 新高度（像素，必须 >0）
    * @return bool - 操作结果：true 表示调整成功，false 表示尺寸无效或资源更新失败
    */
   bool              Resize(const int width,const int height);

   //--- 画布清空与填充接口
   /**
    * @brief 清空画布（用指定颜色填充所有像素）
    * @param clr [in] 填充颜色（默认：0，即黑色透明）
    */
   void              Erase(const uint clr=0);

   //--- 像素级操作接口
   /**
    * @brief 获取指定坐标的像素颜色
    * @param x [in] 像素 X 坐标（0 <= x < Width()）
    * @param y [in] 像素 Y 坐标（0 <= y < Height()）
    * @return uint - 像素颜色值（ARGB/XRGB 格式），坐标无效返回 0
    */
   uint              PixelGet(const int x,const int y) const;

   /**
    * @brief 设置指定坐标的像素颜色
    * @param x [in] 像素 X 坐标（0 <= x < Width()）
    * @param y [in] 像素 Y 坐标（0 <= y < Height()）
    * @param clr [in] 要设置的颜色值（ARGB/XRGB 格式）
    * @note 坐标无效时无操作
    */
   void              PixelSet(const int x,const int y,const uint clr);

   //--- 基础图形绘制接口（无抗锯齿，基于 Bresenham 等经典算法）
   /**
    * @brief 绘制垂直线（X 坐标固定，Y 坐标范围为 [y1, y2]）
    * @param x [in] 直线 X 坐标
    * @param y1 [in] 直线起始 Y 坐标
    * @param y2 [in] 直线结束 Y 坐标（无需提前排序，内部会自动处理）
    * @param clr [in] 直线颜色
    */
   void              LineVertical(int x,int y1,int y2,const uint clr);

   /**
    * @brief 绘制水平线（Y 坐标固定，X 坐标范围为 [x1, x2]）
    * @param x1 [in] 直线起始 X 坐标
    * @param x2 [in] 直线结束 X 坐标（无需提前排序，内部会自动处理）
    * @param y [in] 直线 Y 坐标
    * @param clr [in] 直线颜色
    */
   void              LineHorizontal(int x1,int x2,int y,const uint clr);

   /**
    * @brief 绘制任意两点之间的直线（基于 Bresenham 算法，无抗锯齿）
    * @param x1 [in] 起点 X 坐标
    * @param y1 [in] 起点 Y 坐标
    * @param x2 [in] 终点 X 坐标
    * @param y2 [in] 终点 Y 坐标
    * @param clr [in] 直线颜色
    */
   void              Line(int x1,int y1,int x2,int y2,const uint clr);

   /**
    * @brief 绘制折线（连接数组中连续的坐标点，不闭合）
    * @param x [in] X 坐标数组（与 y 数组长度需一致）
    * @param y [in] Y 坐标数组（与 x 数组长度需一致，至少 2 个点）
    * @param clr [in] 折线颜色
    */
   void              Polyline(int &x[],int &y[],const uint clr);

   /**
    * @brief 绘制多边形（连接数组中连续的坐标点，最后闭合到起点）
    * @param x [in] X 坐标数组（与 y 数组长度需一致）
    * @param y [in] Y 坐标数组（与 x 数组长度需一致，至少 3 个点）
    * @param clr [in] 多边形边框颜色
    */
   void              Polygon(int &x[],int &y[],const uint clr);

   /**
    * @brief 绘制矩形（基于对角两点坐标，无填充）
    * @param x1 [in] 第一个对角点 X 坐标
    * @param y1 [in] 第一个对角点 Y 坐标
    * @param x2 [in] 第二个对角点 X 坐标
    * @param y2 [in] 第二个对角点 Y 坐标（无需提前排序，内部会自动处理）
    * @param clr [in] 矩形边框颜色
    */
   void              Rectangle(int x1,int y1,int x2,int y2,const uint clr);

   /**
    * @brief 绘制三角形（基于三个顶点坐标，无填充）
    * @param x1 [in] 顶点 1 X 坐标
    * @param y1 [in] 顶点 1 Y 坐标
    * @param x2 [in] 顶点 2 X 坐标
    * @param y2 [in] 顶点 2 Y 坐标
    * @param x3 [in] 顶点 3 X 坐标
    * @param y3 [in] 顶点 3 Y 坐标
    * @param clr [in] 三角形边框颜色
    */
   void              Triangle(int x1,int y1,int x2,int y2,int x3,int y3,const uint clr);

   /**
    * @brief 绘制圆形（基于圆心和半径，无填充）
    * @param x [in] 圆心 X 坐标
    * @param y [in] 圆心 Y 坐标
    * @param r [in] 半径（像素，必须 >0）
    * @param clr [in] 圆形边框颜色
    */
   void              Circle(int x,int y,int r,const uint clr);

   /**
    * @brief 绘制椭圆（基于外接矩形对角两点，无填充）
    * @param x1 [in] 外接矩形第一个对角点 X 坐标
    * @param y1 [in] 外接矩形第一个对角点 Y 坐标
    * @param x2 [in] 外接矩形第二个对角点 X 坐标
    * @param y2 [in] 外接矩形第二个对角点 Y 坐标
    * @param clr [in] 椭圆边框颜色
    */
   void              Ellipse(int x1,int y1,int x2,int y2,const uint clr);

   /**
    * @brief 绘制椭圆弧（基于外接矩形和两条射线，无填充）
    * @param x1 [in] 外接矩形第一个对角点 X 坐标
    * @param y1 [in] 外接矩形第一个对角点 Y 坐标
    * @param x2 [in] 外接矩形第二个对角点 X 坐标
    * @param y2 [in] 外接矩形第二个对角点 Y 坐标
    * @param x3 [in] 第一条射线端点 X 坐标（从椭圆中心出发）
    * @param y3 [in] 第一条射线端点 Y 坐标
    * @param x4 [in] 第二条射线端点 X 坐标（从椭圆中心出发）
    * @param y4 [in] 第二条射线端点 Y 坐标
    * @param clr [in] 弧线颜色
    */
   void              Arc(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4,const uint clr);

   /**
    * @brief 绘制椭圆弧（基于圆心、半轴和角度范围，无填充）
    * @param x [in] 椭圆中心 X 坐标
    * @param y [in] 椭圆中心 Y 坐标
    * @param rx [in] X 轴方向半轴长度（像素，必须 >0）
    * @param ry [in] Y 轴方向半轴长度（像素，必须 >0）
    * @param fi3 [in] 起始角度（弧度，0 表示水平向右，逆时针为正）
    * @param fi4 [in] 结束角度（弧度，需大于起始角度，范围 0~2π）
    * @param clr [in] 弧线颜色
    */
   void              Arc(int x,int y,int rx,int ry,double fi3,double fi4,const uint clr);

   /**
    * @brief 绘制椭圆弧并获取弧线与射线的交点（无填充）
    * @param x [in] 椭圆中心 X 坐标
    * @param y [in] 椭圆中心 Y 坐标
    * @param rx [in] X 轴方向半轴长度（像素，必须 >0）
    * @param ry [in] Y 轴方向半轴长度（像素，必须 >0）
    * @param fi3 [in] 起始角度（弧度）
    * @param fi4 [in] 结束角度（弧度）
    * @param x3 [out] 第一条射线与弧线交点 X 坐标
    * @param y3 [out] 第一条射线与弧线交点 Y 坐标
    * @param x4 [out] 第二条射线与弧线交点 X 坐标
    * @param y4 [out] 第二条射线与弧线交点 Y 坐标
    * @param clr [in] 弧线颜色
    */
   void              Arc(int x,int y,int rx,int ry,double fi3,double fi4,int &x3,int &y3,int &x4,int &y4,const uint clr);

   /**
    * @brief 绘制扇形（基于椭圆弧和两条射线，带边框和填充）
    * @param x1 [in] 外接矩形第一个对角点 X 坐标
    * @param y1 [in] 外接矩形第一个对角点 Y 坐标
    * @param x2 [in] 外接矩形第二个对角点 X 坐标
    * @param y2 [in] 外接矩形第二个对角点 Y 坐标
    * @param x3 [in] 第一条射线端点 X 坐标
    * @param y3 [in] 第一条射线端点 Y 坐标
    * @param x4 [in] 第二条射线端点 X 坐标
    * @param y4 [in] 第二条射线端点 Y 坐标
    * @param clr [in] 扇形边框颜色
    * @param fill_clr [in] 扇形填充颜色
    */
   void              Pie(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4,const uint clr,const uint fill_clr);

   /**
    * @brief 绘制扇形（基于圆心、半轴和角度范围，带边框和填充）
    * @param x [in] 椭圆中心 X 坐标
    * @param y [in] 椭圆中心 Y 坐标
    * @param rx [in] X 轴方向半轴长度（像素，必须 >0）
    * @param ry [in] Y 轴方向半轴长度（像素，必须 >0）
    * @param fi3 [in] 起始角度（弧度）
    * @param fi4 [in] 结束角度（弧度）
    * @param clr [in] 扇形边框颜色
    * @param fill_clr [in] 扇形填充颜色
    */
   void              Pie(int x,int y,int rx,int ry,double fi3,double fi4,const uint clr,const uint fill_clr);

   //--- 填充图形绘制接口（无抗锯齿，内部基于扫描线算法）
   /**
    * @brief 绘制填充矩形
    * @param x1 [in] 第一个对角点 X 坐标
    * @param y1 [in] 第一个对角点 Y 坐标
    * @param x2 [in] 第二个对角点 X 坐标
    * @param y2 [in] 第二个对角点 Y 坐标
    * @param clr [in] 填充颜色
    */
   void              FillRectangle(int x1,int y1,int x2,int y2,const uint clr);

   /**
    * @brief 绘制填充三角形
    * @param x1 [in] 顶点 1 X 坐标
    * @param y1 [in] 顶点 1 Y 坐标
    * @param x2 [in] 顶点 2 X 坐标
    * @param y2 [in] 顶点 2 Y 坐标
    * @param x3 [in] 顶点 3 X 坐标
    * @param y3 [in] 顶点 3 Y 坐标
    * @param clr [in] 填充颜色
    */
   void              FillTriangle(int x1,int y1,int x2,int y2,int x3,int y3,const uint clr);

   /**
    * @brief 绘制填充多边形（支持凸多边形和简单凹多边形）
    * @param x [in] X 坐标数组（与 y 数组长度需一致，至少 3 个点）
    * @param y [in] Y 坐标数组（与 x 数组长度需一致）
    * @param clr [in] 填充颜色
    */
   void              FillPolygon(int &x[],int &y[],const uint clr);

   /**
    * @brief 绘制填充圆形
    * @param x [in] 圆心 X 坐标
    * @param y [in] 圆心 Y 坐标
    * @param r [in] 半径（像素，必须 >0）
    * @param clr [in] 填充颜色
    */
   void              FillCircle(int x,int y,int r,const uint clr);

   /**
    * @brief 绘制填充椭圆
    * @param x1 [in] 外接矩形第一个对角点 X 坐标
    * @param y1 [in] 外接矩形第一个对角点 Y 坐标
    * @param x2 [in] 外接矩形第二个对角点 X 坐标
    * @param y2 [in] 外接矩形第二个对角点 Y 坐标
    * @param clr [in] 填充颜色
    */
   void              FillEllipse(int x1,int y1,int x2,int y2,const uint clr);

   /**
    * @brief 区域填充（从指定点开始，填充所有相同颜色的连通区域）
    * @param x [in] 起始点 X 坐标
    * @param y [in] 起始点 Y 坐标
    * @param clr [in] 填充颜色
    */
   void              Fill(int x,int y,const uint clr);

   /**
    * @brief 带容差的区域填充（填充颜色相近的连通区域，容差控制相近程度）
    * @param x [in] 起始点 X 坐标
    * @param y [in] 起始点 Y 坐标
    * @param clr [in] 填充颜色
    * @param threshould [in] 颜色容差（0-255，值越大，允许的颜色差异越大）
    */
   void              Fill(int x,int y,const uint clr,const uint threshould);

   //--- 抗锯齿图形绘制接口（基于像素混合算法，边缘更平滑）
   /**
    * @brief 绘制抗锯齿像素（基于坐标周围 4 个像素的颜色混合）
    * @param x [in] 像素 X 坐标（支持小数，如 10.5 表示在 10 和 11 之间）
    * @param y [in] 像素 Y 坐标（支持小数）
    * @param clr [in] 像素颜色（含透明度时效果更明显）
    */
   void              PixelSetAA(const double x,const double y,const uint clr);

   /**
    * @brief 绘制抗锯齿直线（支持自定义线条样式）
    * @param x1 [in] 起点 X 坐标
    * @param y1 [in] 起点 Y 坐标
    * @param x2 [in] 终点 X 坐标
    * @param y2 [in] 终点 Y 坐标
    * @param clr [in] 直线颜色
    * @param style [in] 线条样式（默认 UINT_MAX，使用当前设置的样式；可传 STYLE_SOLID 等常量）
    */
   void              LineAA(const int x1,const int y1,const int x2,const int y2,const uint clr,const uint style=UINT_MAX);

   /**
    * @brief 绘制抗锯齿折线
    * @param x [in] X 坐标数组（与 y 数组长度需一致，至少 2 个点）
    * @param y [in] Y 坐标数组
    * @param clr [in] 折线颜色
    * @param style [in] 线条样式（默认 UINT_MAX，使用当前设置的样式）
    */
   void              PolylineAA(int &x[],int &y[],const uint clr,const uint style=UINT_MAX);

   /**
    * @brief 绘制抗锯齿多边形
    * @param x [in] X 坐标数组（与 y 数组长度需一致，至少 3 个点）
    * @param y [in] Y 坐标数组
    * @param clr [in] 多边形边框颜色
    * @param style [in] 线条样式（默认 UINT_MAX，使用当前设置的样式）
    */
   void              PolygonAA(int &x[],int &y[],const uint clr,const uint style=UINT_MAX);

   /**
    * @brief 绘制抗锯齿三角形
    * @param x1 [in] 顶点 1 X 坐标
    * @param y1 [in] 顶点 1 Y 坐标
    * @param x2 [in] 顶点 2 X 坐标
    * @param y2 [in] 顶点 2 Y 坐标
    * @param x3 [in] 顶点 3 X 坐标
    * @param y3 [in] 顶点 3 Y 坐标
    * @param clr [in] 三角形边框颜色
    * @param style [in] 线条样式（默认 UINT_MAX，使用当前设置的样式）
    */
   void              TriangleAA(const int x1,const int y1,const int x2,const int y2,const int x3,const int y3,
                                const uint clr,const uint style=UINT_MAX);

   /**
    * @brief 绘制抗锯齿圆形
    * @param x [in] 圆心 X 坐标
    * @param y [in] 圆心 Y 坐标
    * @param r [in] 半径（像素，支持小数，如 10.5）
    * @param clr [in] 圆形边框颜色
    * @param style [in] 线条样式（默认 UINT_MAX，使用当前设置的样式）
    */
   void              CircleAA(const int x,const int y,const double r,const uint clr,const uint style=UINT_MAX);

   /**
    * @brief 绘制抗锯齿椭圆
    * @param x1 [in] 外接矩形第一个对角点 X 坐标（支持小数）
    * @param y1 [in] 外接矩形第一个对角点 Y 坐标（支持小数）
    * @param x2 [in] 外接矩形第二个对角点 X 坐标（支持小数）
    * @param y2 [in] 外接矩形第二个对角点 Y 坐标（支持小数）
    * @param clr [in] 椭圆边框颜色
    * @param style [in] 线条样式（默认 UINT_MAX，使用当前设置的样式）
    */
   void              EllipseAA(const double x1,const double y1,const double x2,const double y2,const uint clr,const uint style=UINT_MAX);

   //--- Wu 算法抗锯齿绘制接口（更精细的边缘平滑，适合高要求场景）
   /**
    * @brief 基于 Wu 算法绘制抗锯齿直线
    * @param x1 [in] 起点 X 坐标
    * @param y1 [in] 起点 Y 坐标
    * @param x2 [in] 终点 X 坐标
    * @param y2 [in] 终点 Y 坐标
    * @param clr [in] 直线颜色
    * @param style [in] 线条样式（默认 UINT_MAX，使用当前设置的样式）
    */
   void              LineWu(int x1,int y1,int x2,int y2,const uint clr,const uint style=UINT_MAX);

   /**
    * @brief 基于 Wu 算法绘制抗锯齿折线
    * @param x [in] X 坐标数组（与 y 数组长度需一致，至少 2 个点）
    * @param y [in] Y 坐标数组
    * @param clr [in] 折线颜色
    * @param style [in] 线条样式（默认 UINT_MAX，使用当前设置的样式）
    */
   void              PolylineWu(const int &x[],const int &y[],const uint clr,const uint style=UINT_MAX);

   /**
    * @brief 基于 Wu 算法绘制抗锯齿多边形
    * @param x [in] X 坐标数组（与 y 数组长度需一致，至少 3 个点）
    * @param y [in] Y 坐标数组
    * @param clr [in] 多边形边框颜色
    * @param style [in] 线条样式（默认 UINT_MAX，使用当前设置的样式）
    */
   void              PolygonWu(const int &x[],const int &y[],const uint clr,const uint style=UINT_MAX);

   /**
    * @brief 基于 Wu 算法绘制抗锯齿三角形
    * @param x1 [in] 顶点 1 X 坐标
    * @param y1 [in] 顶点 1 Y 坐标
    * @param x2 [in] 顶点 2 X 坐标
    * @param y2 [in] 顶点 2 Y 坐标
    * @param x3 [in] 顶点 3 X 坐标
    * @param y3 [in] 顶点 3 Y 坐标
    * @param clr [in] 三角形边框颜色
    * @param style [in] 线条样式（默认 UINT_MAX，使用当前设置的样式）
    */
   void              TriangleWu(const int x1,const int y1,const int x2,const int y2,const int x3,const int y3,const uint clr,const uint style=UINT_MAX);

   /**
    * @brief 基于 Wu 算法绘制抗锯齿圆形
    * @param x [in] 圆心 X 坐标
    * @param y [in] 圆心 Y 坐标
    * @param r [in] 半径（像素，支持小数）
    * @param clr [in] 圆形边框颜色
    * @param style [in] 线条样式（默认 UINT_MAX，使用当前设置的样式）
    */
   void              CircleWu(const int x,const int y,const double r,const uint clr,const uint style=UINT_MAX);

   /**
    * @brief 基于 Wu 算法绘制抗锯齿椭圆
    * @param x1 [in] 外接矩形第一个对角点 X 坐标
    * @param y1 [in] 外接矩形第一个对角点 Y 坐标
    * @param x2 [in] 外接矩形第二个对角点 X 坐标
    * @param y2 [in] 外接矩形第二个对角点 Y 坐标
    * @param clr [in] 椭圆边框颜色
    * @param style [in] 线条样式（默认 UINT_MAX，使用当前设置的样式）
    */
   void              EllipseWu(const int x1,const int y1,const int x2,const int y2,const uint clr,const uint style=UINT_MAX);

   //--- 带预过滤抗锯齿的粗线条绘制接口（支持线条宽度和端点样式）
   /**
    * @brief 绘制粗垂直线（带预过滤抗锯齿，边缘平滑）
    * @param x [in] 直线 X 坐标
    * @param y1 [in] 直线起始 Y 坐标
    * @param y2 [in] 直线结束 Y 坐标
    * @param clr [in] 线条颜色
    * @param size [in] 线条宽度（像素，>2 时生效，<=2 自动调用 LineWu）
    * @param style [in] 线条样式（如 STYLE_SOLID/STYLE_DASH）
    * @param end_style [in] 线条端点样式（LINE_END_ROUND 等）
    */
   void              LineThickVertical(const int x,const int y1,const int y2,const uint clr,const int size,const uint style,ENUM_LINE_END end_style);

   /**
    * @brief 绘制粗水平线（带预过滤抗锯齿）
    * @param x1 [in] 直线起始 X 坐标
    * @param x2 [in] 直线结束 X 坐标
    * @param y [in] 直线 Y 坐标
    * @param clr [in] 线条颜色
    * @param size [in] 线条宽度（像素，>2 时生效）
    * @param style [in] 线条样式
    * @param end_style [in] 线条端点样式
    */
   void              LineThickHorizontal(const int x1,const int x2,int y,const uint clr,const int size,const uint style,ENUM_LINE_END end_style);

   /**
    * @brief 绘制任意方向的粗线条（带预过滤抗锯齿）
    * @param x1 [in] 起点 X 坐标
    * @param y1 [in] 起点 Y 坐标
    * @param x2 [in] 终点 X 坐标
    * @param y2 [in] 终点 Y 坐标
    * @param clr [in] 线条颜色
    * @param size [in] 线条宽度（像素，>2 时生效）
    * @param style [in] 线条样式
    * @param end_style [in] 线条端点样式
    */
   void              LineThick(const int x1,const int y1,const int x2,const int y2,const uint clr,const int size,const uint style,ENUM_LINE_END end_style);

   /**
    * @brief 绘制粗折线（带预过滤抗锯齿）
    * @param x [in] X 坐标数组（与 y 数组长度需一致，至少 2 个点）
    * @param y [in] Y 坐标数组
    * @param clr [in] 折线颜色
    * @param size [in] 线条宽度（像素，>2 时生效）
    * @param style [in] 线条样式
    * @param end_style [in] 线条端点样式
    */
   void              PolylineThick(const int &x[],const int &y[],const uint clr,const int size,const uint style,ENUM_LINE_END end_style);

   /**
    * @brief 绘制粗多边形（带预过滤抗锯齿）
    * @param x [in] X 坐标数组（与 y 数组长度需一致，至少 3 个点）
    * @param y [in] Y 坐标数组
    * @param clr [in] 多边形边框颜色
    * @param size [in] 线条宽度（像素，>2 时生效）
    * @param style [in] 线条样式
    * @param end_style [in] 线条端点样式
    */
   void              PolygonThick(const int &x[],const int &y[],const uint clr,const int size,const uint style,ENUM_LINE_END end_style);

   //--- 平滑曲线绘制接口（基于贝塞尔曲线，优化折线/多边形的尖角）
   /**
    * @brief 绘制平滑折线（将折线顶点处的尖角替换为贝塞尔曲线过渡）
    * @param x [in] X 坐标数组（与 y 数组长度需一致，至少 2 个点）
    * @param y [in] Y 坐标数组
    * @param clr [in] 折线颜色
    * @param size [in] 线条宽度（像素，>2 时生效）
    * @param style [in] 线条样式（默认 STYLE_SOLID）
    * @param end_style [in] 线条端点样式（默认 LINE_END_ROUND）
    * @param tension [in] 曲线张力（0~1，值越大，曲线越弯曲，默认 0.5）
    * @param step [in] 曲线采样步长（像素，值越小，曲线越平滑，默认 10）
    */
   void              PolylineSmooth(const int &x[],const int &y[],const uint clr,const int size,
                                    ENUM_LINE_STYLE style=STYLE_SOLID,ENUM_LINE_END end_style=LINE_END_ROUND,
                                    double tension=0.5,double step=10);

   /**
    * @brief 绘制平滑多边形（将多边形顶点处的尖角替换为贝塞尔曲线过渡）
    * @param x [in] X 坐标数组（与 y 数组长度需一致，至少 3 个点）
    * @param y [in] Y 坐标数组
    * @param clr [in] 多边形边框颜色
    * @param size [in] 线条宽度（像素，>2 时生效）
    * @param style [in] 线条样式（默认 STYLE_SOLID）
    * @param end_style [in] 线条端点样式（默认 LINE_END_ROUND）
    * @param tension [in] 曲线张力（0~1，默认 0.5）
    * @param step [in] 曲线采样步长（像素，默认 10）
    */
   void              PolygonSmooth(int &x[],int &y[],const uint clr,const int size,
                                   ENUM_LINE_STYLE style=STYLE_SOLID,ENUM_LINE_END end_style=LINE_END_ROUND,
                                   double tension=0.5,double step=10);

   //--- 位图复制接口（BitBlt，快速复制像素块）
   /**
    * @brief 从源像素数组复制指定区域到当前画布
    * @param dst_x [in] 目标区域左上角 X 坐标（当前画布）
    * @param dst_y [in] 目标区域左上角 Y 坐标（当前画布）
    * @param src [in] 源像素数组（格式需与当前画布一致）
    * @param src_width [in] 源像素数组的宽度（像素）
    * @param src_height [in] 源像素数组的高度（像素）
    * @param src_x [in] 源区域左上角 X 坐标（源像素数组）
    * @param src_y [in] 源区域左上角 Y 坐标（源像素数组）
    * @param src_dx [in] 源区域宽度（像素）
    * @param src_dy [in] 源区域高度（像素）
    * @param mode [in] 复制模式（默认 0，直接覆盖；预留扩展位）
    */
   void              BitBlt(int dst_x,int dst_y,const uint &src[],int src_width,int src_height,int src_x,int src_y,int src_dx,int src_dy,uint mode=0);

   //--- 文本渲染接口
   /**
    * @brief 设置文本字体（名称、大小、样式、角度）
    * @param name [in] 字体名称（如 "Arial"、"SimSun"）
    * @param size [in] 字体大小（负值表示像素单位，如 -12 表示 12px；正值表示点（pt））
    * @param flags [in] 字体样式标志（如 FS_BOLD 粗体、FS_ITALIC 斜体，多个标志用 | 组合）
    * @param angle [in] 文本倾斜角度（相对于 X 轴，单位：0.1 度，0 表示水平，顺时针为正）
    * @return bool - 操作结果：true 表示字体设置成功，false 表示字体不存在或参数无效
    */
   bool              FontSet(const string name,const int size,const uint flags=0,const uint angle=0);

   /**
    * @brief 设置文本字体名称
    * @param name [in] 字体名称（如 "SimHei"）
    * @return bool - 操作结果：true 表示设置成功，false 表示字体不存在
    */
   bool              FontNameSet(string name);

   /**
    * @brief 设置文本字体大小
    * @param size [in] 字体大小（负值像素，正值点）
    * @return bool - 操作结果：true 表示设置成功，false 表示大小无效
    */
   bool              FontSizeSet(int size);

   /**
    * @brief 设置文本字体样式（粗体、斜体等）
    * @param flags [in] 字体样式标志（FS_* 常量组合）
    * @return bool - 操作结果：true 表示设置成功，false 表示标志无效
    */
   bool              FontFlagsSet(uint flags);

   /**
    * @brief 设置文本倾斜角度
    * @param angle [in] 倾斜角度（0.1 度为单位，范围 0~3600，即 0~360 度）
    * @return bool - 操作结果：true 表示设置成功，false 表示角度无效
    */
   bool              FontAngleSet(uint angle);

   /**
    * @brief 获取当前文本字体的所有参数
    * @param name [out] 字体名称
    * @param size [out] 字体大小
    * @param flags [out] 字体样式标志
    * @param angle [out] 文本倾斜角度
    */
   void              FontGet(string &name,int &size,uint &flags,uint &angle);

   /**
    * @brief 获取当前字体名称
    * @return string - 字体名称（如 "Arial"）
    */
   string            FontNameGet(void)                 const { return(m_fontname);  }

   /**
    * @brief 获取当前字体大小
    * @return int - 字体大小（负值像素，正值点）
    */
   int               FontSizeGet(void)                 const { return(m_fontsize);  }

   /**
    * @brief 获取当前字体样式标志
    * @return uint - 样式标志（FS_* 常量组合）
    */
   uint              FontFlagsGet(void)                const { return(m_fontflags); }

   /**
    * @brief 获取当前文本倾斜角度
    * @return uint - 倾斜角度（0.1 度为单位）
    */
   uint              FontAngleGet(void)                const { return(m_fontangle); }

   /**
    * @brief 在指定位置绘制文本
    * @param x [in] 文本绘制基准点 X 坐标
    * @param y [in] 文本绘制基准点 Y 坐标
    * @param text [in] 要绘制的文本（支持 Unicode，如中文）
    * @param clr [in] 文本颜色
    * @param alignment [in] 文本对齐方式（如 TA_LEFT 左对齐、TA_CENTER 居中，见 MT5 常量）
    */
   void              TextOut(int x,int y,string text,const uint clr,uint alignment=0);

   /**
    * @brief 计算指定文本的宽度（基于当前字体设置）
    * @param text [in] 要计算的文本
    * @return int - 文本宽度（像素），字体未设置返回 0
    */
   int               TextWidth(const string text);

   /**
    * @brief 计算指定文本的高度（基于当前字体设置）
    * @param text [in] 要计算的文本
    * @return int - 文本高度（像素），字体未设置返回 0
    */
   int               TextHeight(const string text);

   /**
    * @brief 计算指定文本的宽高（基于当前字体设置）
    * @param text [in] 要计算的文本
    * @param width [out] 文本宽度（像素）
    * @param height [out] 文本高度（像素）
    */
   void              TextSize(const string text,int &width,int &height);

   //--- 辅助服务接口
   /**
    * @brief 获取预定义的默认颜色（静态方法，无需实例化即可调用）
    * @param i [in] 颜色索引（0-8，对应 9 种预定义颜色）
    * @return uint - 颜色值（XRGB 格式），索引无效时返回自动生成的颜色
    */
   static uint       GetDefaultColor(const int i);

   /**
    * @brief 设置整个画布的透明度（统一修改所有像素的 Alpha 通道）
    * @param value [in] 透明度值（0-255，0 全透明，255 不透明）
    */
   void              TransparentLevelSet(const uchar value);

   //--- 位图文件读写接口
   /**
    * @brief 从位图文件加载数据到当前画布（支持 BMP 格式）
    * @param filename [in] 位图文件路径（绝对路径或相对路径，如 "C:\\test.bmp"）
    * @return bool - 操作结果：true 表示加载成功，false 表示文件不存在或格式不支持
    */
   bool              LoadFromFile(const string filename);

   //--- 线条样式接口
   /**
    * @brief 获取当前线条样式
    * @return uint - 线条样式（STYLE_SOLID 等常量，或自定义位掩码）
    */
   uint              LineStyleGet(void) const;

   /**
    * @brief 设置线条样式
    * @param style [in] 线条样式（支持 STYLE_SOLID/STYLE_DASH 等预定义常量，或自定义位掩码）
    * @note 自定义样式需设置最高位（0x80000000），否则视为预定义样式
    */
   void              LineStyleSet(const uint style);

   /**
    * @brief 从位图文件加载像素数据到指定数组（静态方法，无需实例化）
    * @param filename [in] 位图文件路径
    * @param data [out] 输出像素数组（ARGB 格式）
    * @param width [out] 位图宽度（像素）
    * @param height [out] 位图高度（像素）
    * @return bool - 操作结果：true 表示加载成功，false 表示文件无效或格式不支持
    */
   static bool       LoadBitmap(const string filename,uint &data[],int &width,int &height);

private:
   /**
    * @brief 内部方法：应用当前字体设置（供 TextOut 等方法调用）
    * @return bool - 操作结果：true 表示字体应用成功，false 表示字体无效
    */
   bool              FontSet(void);

   /**
    * @brief 内部方法：快速绘制文本（跳过部分参数检查，提高效率）
    * @param x [in] 绘制基准点 X 坐标
    * @param y [in] 绘制基准点 Y 坐标
    * @param text [in] 要绘制的文本
    * @param clr [in] 文本颜色
    * @param alignment [in] 文本对齐方式
    */
   void              TextOutFast(int x,int y,string text,const uint clr,uint alignment=0);

   /**
    * @brief 内部方法：判断两个颜色是否相似（基于 RGB 通道差异）
    * @param clr0 [in] 第一个颜色值
    * @param clr1 [in] 第二个颜色值
    * @param threshould [in] 颜色容差（0-255）
    * @return bool - 判断结果：true 表示相似，false 表示差异超过容差
    */
   bool              PixelsSimilar(const uint clr0,const uint clr1,const uint threshould);

   //--- Wu 算法相关内部方法
   /**
    * @brief 内部方法：像素颜色混合（用于 Wu 算法抗锯齿）
    * @param x [in] 像素 X 坐标
    * @param y [in] 像素 Y 坐标
    * @param clr [in] 目标颜色
    * @param alpha [in] 混合透明度（0-1，1 表示完全覆盖）
    */
   void              PixelTransform(const int x,const int y,const uint clr,const double alpha);

   //--- 圆形/椭圆绘制相关内部方法
   /**
    * @brief 内部方法：同时处理 4 个对称像素的颜色混合（用于圆形/椭圆抗锯齿）
    * @param x [in] 圆心 X 坐标
    * @param y [in] 圆心 Y 坐标
    * @param dx [in] X 方向偏移
    * @param dy [in] Y 方向偏移
    * @param clr [in] 目标颜色
    * @param alpha [in] 混合透明度（0-1）
    */
   void              PixelTransform4(const int x,const int y,const int dx,const int dy,const uint clr,const double alpha);

   /**
    * @brief 内部方法：同时处理 4 个对称像素的抗锯齿绘制
    * @param x [in] 圆心 X 坐标
    * @param y [in] 圆心 Y 坐标
    * @param dx [in] X 方向偏移
    * @param dy [in] Y 方向偏移
    * @param clr [in] 目标颜色
    */
   void              PixelSet4AA(const double x,const double y,const double dx,const double dy,const uint clr);

   //--- 粗线条绘制相关内部方法
   /**
    * @brief 内部方法：绘制粗垂直线的线段（带预过滤抗锯齿）
    * @param x [in] 线段 X 坐标
    * @param y1 [in] 线段起始 Y 坐标
    * @param y2 [in] 线段结束 Y 坐标
    * @param ysign [in] Y 方向符号（1 或 -1）
    * @param r [in] 线条半宽（像素）
    * @param clr [in] 线条颜色
    * @param end_style [in] 端点样式
    */
   void              SegmentVertical(const int x,const int y1,const int y2,const int ysign,const double r,const uint clr,ENUM_LINE_END end_style);

   /**
    * @brief 内部方法：绘制粗水平线的线段（带预过滤抗锯齿）
    * @param x1 [in] 线段起始 X 坐标
    * @param x2 [in] 线段结束 X 坐标
    * @param y [in] 线段 Y 坐标
    * @param xsign [in] X 方向符号（1 或 -1）
    * @param r [in] 线条半宽（像素）
    * @param clr [in] 线条颜色
    * @param end_style [in] 端点样式
    */
   void              SegmentHorizontal(const int x1,const int x2,const int y,const int xsign,const double r,const uint clr,ENUM_LINE_END end_style);

   /**
    * @brief 内部方法：绘制任意方向粗线条的线段（带预过滤抗锯齿）
    * @param x1 [in] 线段起点 X 坐标
    * @param y1 [in] 线段起点 Y 坐标
    * @param x2 [in] 线段终点 X 坐标
    * @param y2 [in] 线段终点 Y 坐标
    * @param kp0 [in] 边缘函数系数 0
    * @param kp1 [in] 边缘函数系数 1
    * @param xsign [in] X 方向符号（1 或 -1）
    * @param ysign [in] Y 方向符号（1 或 -1）
    * @param rcos_k [in] 线条半宽 * cos(角度)
    * @param rsin_k [in] 线条半宽 * sin(角度)
    * @param r [in] 线条半宽（像素）
    * @param clr [in] 线条颜色
    * @param end_style [in] 端点样式
    */
   void              Segment(const int x1,const int y1,const int x2,const int y2,const double kp0,const double kp1,const int xsign,const int ysign,
                             const double rcos_k,const double rsin_k,const double r,const uint clr,ENUM_LINE_END end_style);

   /**
    * @brief 内部方法：计算点到线段的最短距离
    * @param px [in] 目标点 X 坐标
    * @param py [in] 目标点 Y 坐标
    * @param x1 [in] 线段起点 X 坐标
    * @param y1 [in] 线段起点 Y 坐标
    * @param x2 [in] 线段终点 X 坐标
    * @param y2 [in] 线段终点 Y 坐标
    * @return double - 最短距离（像素）
    */
   double            DistancePointSegment(const double px,const double py,const double x1,const double y1,const double x2,const double y2);

   //--- 扇形绘制相关内部方法
   /**
    * @brief 内部方法：计算两条射线之间的角度（基于两点坐标）
    * @param x1 [in] 射线起点 X 坐标
    * @param y1 [in] 射线起点 Y 坐标
    * @param x2 [in] 射线端点 X 坐标
    * @param y2 [in] 射线端点 Y 坐标
    * @return double - 角度（弧度，范围 0~2π）
    */
   double            AngleCalc(int x1,int y1,int x2,int y2);

   //--- 多边形绘制相关内部方法
   /**
    * @brief 内部方法：判断点相对于线段的位置（用于多边形凹凸性判断）
    * @param p0 [in] 线段起点
    * @param p1 [in] 线段终点
    * @param p2 [in] 目标点
    * @return int - 位置标识（>0 逆时针，<0 顺时针，=0 共线）
    */
   int               PointClassify(const CPoint &p0,const CPoint &p1,const CPoint &p2);

   /**
    * @brief 内部方法：判断多边形的顶点环绕方向（顺时针/逆时针）
    * @param p [in] 多边形顶点数组
    * @return int - 环绕方向（>0 逆时针，<0 顺时针）
    */
   int               PolygonClassify(const CPoint &p[]);

   /**
    * @brief 内部方法：判断多边形是否为凸多边形
    * @param p [in] 多边形顶点数组
    * @return bool - 判断结果：true 表示凸多边形，false 表示凹多边形
    */
   bool              IsPolygonConvex(CPoint &p[]);

   /**
    * @brief 内部方法：规范化多边形顶点顺序（将左上角顶点作为第一个顶点）
    * @param p [in/out] 多边形顶点数组（会被修改）
    */
   void              PolygonNormalize(CPoint &p[]);

   /**
    * @brief 内部方法：将凹多边形分割为两个简单多边形
    * @param p [in/out] 原始凹多边形顶点数组（会被修改为第一个子多边形）
    * @param add [out] 第二个子多边形顶点数组
    */
   void              PolygonIntersect(CPoint &p[],CPoint &add[]);

   /**
    * @brief 内部方法：填充多边形（基于扫描线算法，供 FillPolygon 调用）
    * @param p [in] 多边形顶点数组（需规范化）
    * @param clr [in] 填充颜色
    */
   void              PolygonFill(CPoint &p[],const uint clr);

   //--- 平滑曲线相关内部方法
   /**
    * @brief 内部方法：计算贝塞尔曲线的端点控制 points（用于折线首尾平滑）
    * @param xend [in] 折线端点 X 坐标
    * @param yend [in] 折线端点 Y 坐标
    * @param xadj [in] 相邻点 X 坐标
    * @param yadj [in] 相邻点 Y 坐标
    * @param tension [in] 曲线张力
    * @param x [out] 控制 point X 坐标
    * @param y [out] 控制 point Y 坐标
    */
   void              CalcCurveBezierEndp(const double xend,const double yend,const double xadj,const double yadj,const double tension,double &x,double &y);

   /**
    * @brief 内部方法：计算贝塞尔曲线的中间控制 points（用于折线顶点平滑）
    * @param x [in] 折线 X 坐标数组
    * @param y [in] 折线 Y 坐标数组
    * @param i [in] 当前顶点索引
    * @param tension [in] 曲线张力
    * @param x1 [out] 第一个控制 point X 坐标
    * @param y1 [out] 第一个控制 point Y 坐标
    * @param x2 [out] 第二个控制 point X 坐标
    * @param y2 [out] 第二个控制 point Y 坐标
    */
   void              CalcCurveBezier(const int &x[],const int &y[],const int i,const double tension,double &x1,double &y1,double &x2,double &y2);

   /**
    * @brief 内部方法：计算贝塞尔曲线上指定参数的 X 坐标
    * @param t [in] 曲线参数（0~1，0 表示起点，1 表示终点）
    * @param x0 [in] 起点 X 坐标
    * @param x1 [in] 第一个控制 point X 坐标
    * @param x2 [in] 第二个控制 point X 坐标
    * @param x3 [in] 终点 X 坐标
    * @return double - 曲线上对应点的 X 坐标
    */
   double            CalcBezierX(const double t,const double x0,const double x1,const double x2,const double x3);

   /**
    * @brief 内部方法：计算贝塞尔曲线上指定参数的 Y 坐标
    * @param t [in] 曲线参数（0~1）
    * @param y0 [in] 起点 Y 坐标
    * @param y1 [in] 第一个控制 point Y 坐标
    * @param y2 [in] 第二个控制 point Y 坐标
    * @param y3 [in] 终点 Y 坐标
    * @return double - 曲线上对应点的 Y 坐标
    */
   double            CalcBezierY(const double t,const double y0,const double y1,const double y2,const double y3);

protected:
   /**
    * @brief 虚方法：预过滤抗锯齿的过滤函数（用于粗线条边缘平滑）
    * @param x [in] 归一化距离（0~1，0 表示线条中心，1 表示边缘）
    * @return double - 过滤后的透明度值（0~1）
    * @note 派生类可重写此方法，自定义抗锯齿效果
    */
   virtual double    FilterFunction(const double x);
  };
//+------------------------------------------------------------------+
//| 静态成员初始化：默认颜色数组（9 种常用颜色，XRGB 格式）            |
//+------------------------------------------------------------------+
uint CCanvas::m_default_colors[9]=
  {
   XRGB(0,0,255),     // 蓝色（索引 0）
   XRGB(255,0,0),     // 红色（索引 1）
   XRGB(0,128,0),     // 绿色（索引 2）
   XRGB(255,242,0),   // 黄色（索引 3）
   XRGB(255,0,128),   // 粉色（索引 4）
   XRGB(0,255,0),     // 青柠绿（索引 5）
   XRGB(185,0,61),    // 深红色（索引 6）
   XRGB(0,183,239),   // 天蓝色（索引 7）
   XRGB(255,128,0)    // 橙色（索引 8）
  };
//+----------------------------------------------------------------